﻿package personajes 
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.Joints.b2RevoluteJointDef;
	import general.Teclas;
	
	/**
	 * ...
	 * @author Adrián Ramis González
	 */
	public class Jugador extends MovieClip
	{
		//Declaración del objeto que interactua con el motor Box2D
		public var mundo:b2World; 
		
		//Otras variables
		public var cuerpo:b2Body;
		
		//Objeto teclado con el que interactuamos
		public var teclado:Teclas;
		
		//Vector para aplicar movimiento
		public var direccion:b2Vec2;
		
		//Constante para tratar mejor los tamaños de box2d
		public const PIXELS_POR_METRO:int = 30;
		
		//Variables para el ragdoll
		public var bodyDef:b2BodyDef;
		public var boxDef:b2PolygonDef = new b2PolygonDef();
		public var circ:b2CircleDef = new b2CircleDef();
		public var jd:b2RevoluteJointDef = new b2RevoluteJointDef();
		
		public var cabeza:b2Body;
		public var torso1:b2Body;
		public var torso2:b2Body;
		public var torso3:b2Body;
		public var brazoI:b2Body;
		public var brazoD:b2Body;
		public var antebrazoI:b2Body;
		public var antebrazoD:b2Body;
		public var musloI:b2Body;
		public var musloD:b2Body;
		public var tibiaI:b2Body;
		public var tibiaD:b2Body;
		
		/**
		 * Metodo principal de la clase que guarda los parametros en local y crea un heroe
		 * 
		 * @param	teclado
		 * @param	cuerpo
		 * @param	mundo
		 */
		public function Jugador(teclado:Teclas, cuerpo:b2Body, mundo:b2World)
		{
			this.teclado = teclado;
			this.cuerpo = cuerpo;
			this.mundo = mundo;
			
			heroe(350, 5);
			addEventListener(Event.ENTER_FRAME, eventoMovimiento);
		}
		
		/**
		 * Metodo que se ejecuta en cada frame y que va a controlar el movimiento del heroe
		 * 
		 * @param	e
		 */
		private function eventoMovimiento(e:Event):void
		{
			direccion = new b2Vec2();
			
			if (teclado.izq()) 
			{
				direccion.Set(-2, 0);
				cabeza.ApplyImpulse(direccion, cuerpo.GetPosition());
				
			}
			if (teclado.der()) 
			{
				direccion.Set(2, 0);
				cabeza.ApplyImpulse(direccion, cuerpo.GetPosition());

			}
			if (teclado.arriba()) 
			{
				direccion.Set(0, -3);
				cabeza.ApplyImpulse(direccion, cuerpo.GetPosition());

			}
			if (teclado.abajo()) 
			{
				direccion.Set(0, 2);
				cabeza.ApplyImpulse(direccion, cuerpo.GetPosition());

			}
		}
		
		/**
		 * Metodo que inicializa las variables
		 */
		public function inicio():void
		{
			
		}
		
		/**
		 * Metodo para la creacion del heroe
		 * 
		 * @param	px		posicion en el eje x
		 * @param	py		posicion en el eje y
		 */
		public function heroe(px:int, py:int):void
		{
			var startX:Number = px;
			var startY:Number = py;
			
			// CUERPO
			
			// cabeza
			circ.radius = 12.5 / PIXELS_POR_METRO;
			circ.density = 1.0;
			circ.friction = 0.4;
			circ.restitution = 0.3;
			bodyDef = new b2BodyDef();
			bodyDef.position.Set(startX / PIXELS_POR_METRO, startY / PIXELS_POR_METRO);
			cabeza = mundo.CreateBody(bodyDef);
			cabeza.CreateShape(circ);
			cabeza.SetMassFromShapes();
			cabeza.ApplyImpulse(new b2Vec2(Math.random() * 100 - 50, Math.random() * 100 - 50), cabeza.GetWorldCenter());
			
			// Torso1
			boxDef.SetAsBox(15 / PIXELS_POR_METRO, 10 / PIXELS_POR_METRO);
			boxDef.density = 1.0;
			boxDef.friction = 0.4;
			boxDef.restitution = 0.1;
			bodyDef = new b2BodyDef();
			bodyDef.position.Set(startX / PIXELS_POR_METRO, (startY + 28) / PIXELS_POR_METRO);
			torso1 = mundo.CreateBody(bodyDef);
			torso1.CreateShape(boxDef);
			torso1.SetMassFromShapes();
			// Torso2
			bodyDef = new b2BodyDef();
			bodyDef.position.Set(startX / PIXELS_POR_METRO, (startY + 43) / PIXELS_POR_METRO);
			torso2 = mundo.CreateBody(bodyDef);
			torso2.CreateShape(boxDef);
			torso2.SetMassFromShapes();
			// Torso3
			bodyDef = new b2BodyDef();
			bodyDef.position.Set(startX / PIXELS_POR_METRO, (startY + 58) / PIXELS_POR_METRO);
			torso3 = mundo.CreateBody(bodyDef);
			torso3.CreateShape(boxDef);
			torso3.SetMassFromShapes();
			
			// Brazo
			boxDef.SetAsBox(18 / PIXELS_POR_METRO, 6.5 / PIXELS_POR_METRO);
			boxDef.density = 1.0;
			boxDef.friction = 0.4;
			boxDef.restitution = 0.1;
			bodyDef = new b2BodyDef();
			// Izquierdo
			bodyDef.position.Set((startX - 30) / PIXELS_POR_METRO, (startY + 20) / PIXELS_POR_METRO);
			brazoI = mundo.CreateBody(bodyDef);
			brazoI.CreateShape(boxDef);
			brazoI.SetMassFromShapes();
			// Derecho
			bodyDef.position.Set((startX + 30) / PIXELS_POR_METRO, (startY + 20) / PIXELS_POR_METRO);
			brazoD = mundo.CreateBody(bodyDef);
			brazoD.CreateShape(boxDef);
			brazoD.SetMassFromShapes();
			
			// Antebrazo
			boxDef.SetAsBox(17 / PIXELS_POR_METRO, 6 / PIXELS_POR_METRO);
			boxDef.density = 1.0;
			boxDef.friction = 0.4;
			boxDef.restitution = 0.1;
			bodyDef = new b2BodyDef();
			// Izquierdo
			bodyDef.position.Set((startX - 57) / PIXELS_POR_METRO, (startY + 20) / PIXELS_POR_METRO);
			antebrazoI = mundo.CreateBody(bodyDef);
			antebrazoI.CreateShape(boxDef);
			antebrazoI.SetMassFromShapes();
			// Derecho
			bodyDef.position.Set((startX + 57) / PIXELS_POR_METRO, (startY + 20) / PIXELS_POR_METRO);
			antebrazoD = mundo.CreateBody(bodyDef);
			antebrazoD.CreateShape(boxDef);
			antebrazoD.SetMassFromShapes();
			
			// Muslo
			boxDef.SetAsBox(7.5 / PIXELS_POR_METRO, 22 / PIXELS_POR_METRO);
			boxDef.density = 1.0;
			boxDef.friction = 0.4;
			boxDef.restitution = 0.1;
			bodyDef = new b2BodyDef();
			// Izquierdo
			bodyDef.position.Set((startX - 8) / PIXELS_POR_METRO, (startY + 85) / PIXELS_POR_METRO);
			musloI = mundo.CreateBody(bodyDef);
			musloI.CreateShape(boxDef);
			musloI.SetMassFromShapes();
			// Derecho
			bodyDef.position.Set((startX + 8) / PIXELS_POR_METRO, (startY + 85) / PIXELS_POR_METRO);
			musloD = mundo.CreateBody(bodyDef);
			musloD.CreateShape(boxDef);
			musloD.SetMassFromShapes();
			
			// Tibia
			boxDef.SetAsBox(6 / PIXELS_POR_METRO, 20 / PIXELS_POR_METRO);
			boxDef.density = 1.0;
			boxDef.friction = 0.4;
			boxDef.restitution = 0.1;
			bodyDef = new b2BodyDef();
			// Izquierdo
			bodyDef.position.Set((startX - 8) / PIXELS_POR_METRO, (startY + 120) / PIXELS_POR_METRO);
			tibiaI = mundo.CreateBody(bodyDef);
			tibiaI.CreateShape(boxDef);
			tibiaI.SetMassFromShapes();
			// Derecho
			bodyDef.position.Set((startX + 8) / PIXELS_POR_METRO, (startY + 120) / PIXELS_POR_METRO);
			tibiaD = mundo.CreateBody(bodyDef);
			tibiaD.CreateShape(boxDef);
			tibiaD.SetMassFromShapes();
			
			
			// UNIONES
			jd.enableLimit = true;
			
			// cabeza al torso1
			jd.lowerAngle = -40 / (180/Math.PI);
			jd.upperAngle = 40 / (180/Math.PI);
			jd.Initialize(torso1, cabeza, new b2Vec2(startX / PIXELS_POR_METRO, (startY + 15) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			
			// Brazos al torso1
			
			// Izquierdo
			jd.lowerAngle = -85 / (180/Math.PI);
			jd.upperAngle = 130 / (180/Math.PI);
			jd.Initialize(torso1, brazoI, new b2Vec2((startX - 18) / PIXELS_POR_METRO, (startY + 20) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			// Derecho
			jd.lowerAngle = -130 / (180/Math.PI);
			jd.upperAngle = 85 / (180/Math.PI);
			jd.Initialize(torso1, brazoD, new b2Vec2((startX + 18) / PIXELS_POR_METRO, (startY + 20) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			
			// Brazos a antebrazos
			
			// Izquierdo
			jd.lowerAngle = -130 / (180/Math.PI);
			jd.upperAngle = 10 / (180/Math.PI);
			jd.Initialize(brazoI, antebrazoI, new b2Vec2((startX - 45) / PIXELS_POR_METRO, (startY + 20) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			// Derecho
			jd.lowerAngle = -10 / (180/Math.PI);
			jd.upperAngle = 130 / (180/Math.PI);
			jd.Initialize(brazoD, antebrazoD, new b2Vec2((startX + 45) / PIXELS_POR_METRO, (startY + 20) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			
			// Torso1 al torso2
			jd.lowerAngle = -15 / (180/Math.PI);
			jd.upperAngle = 15 / (180/Math.PI);
			jd.Initialize(torso1, torso2, new b2Vec2(startX / PIXELS_POR_METRO, (startY + 35) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			// Torso2 al torso3
			jd.Initialize(torso2, torso3, new b2Vec2(startX / PIXELS_POR_METRO, (startY + 50) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			
			// Muslos al torso3
			// Izquierdo
			jd.lowerAngle = -25 / (180/Math.PI);
			jd.upperAngle = 45 / (180/Math.PI);
			jd.Initialize(torso3, musloI, new b2Vec2((startX - 8) / PIXELS_POR_METRO, (startY + 72) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			// Derecho
			jd.lowerAngle = -45 / (180/Math.PI);
			jd.upperAngle = 25 / (180/Math.PI);
			jd.Initialize(torso3, musloD, new b2Vec2((startX + 8) / PIXELS_POR_METRO, (startY + 72) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			
			//Tibias a los muslos
			// Izquierdo
			jd.lowerAngle = -25 / (180/Math.PI);
			jd.upperAngle = 115 / (180/Math.PI);
			jd.Initialize(musloI, tibiaI, new b2Vec2((startX - 8) / PIXELS_POR_METRO, (startY + 105) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
			// Derecho
			jd.lowerAngle = -115 / (180/Math.PI);
			jd.upperAngle = 25 / (180/Math.PI);
			jd.Initialize(musloD, tibiaD, new b2Vec2((startX + 8) / PIXELS_POR_METRO, (startY + 105) / PIXELS_POR_METRO));
			mundo.CreateJoint(jd);
		}
		
	}
	
}